<?php
/*

function dump($var)
{
	var_dump($var);
	echo "<br />";
}


define("MOCK_ANY",0);
define("MOCK_EQUALS",1);
define("MOCK_ATLEAST",2);
define("MOCK_TIMES",3);

class MockedMethod
{
	public $methodName;
	public $expected = 0;
	public $actual = 0;
	public $return;
	public $multiplicity = 0;
	public $multiplicity_var = 0;
	public $params;
}

class MockedClass
{
	public $className;
	public $replay;
	public $methods = array();

	public function __construct()
	{
		$this->className = "";
		$this->replay = false;
	}
}

class Mock
{
	private static $mockingList = Array();

	public function createMock($className)
	{
		Mock::$mockingList[] = new MockedClass();

		$clazz = new $className();

		$pos = end(array_keys(Mock::$mockingList));
		dump($pos);

		$clazz->mockId = $pos;
		Mock::$mockingList[$pos]->className = $className;

		$r_class = new ReflectionClass($className);
		$r_methods = $r_class->getMethods();

		foreach($r_methods as $method)
		{
			dump($className);
			$temp3 = $method->getName();
			dump($temp3);
			$temp2 = "return Mock::mockRefrenceCount(\$this->mockId,\"$temp3\");";
			dump($temp2);

			$temp4 = array();
			$r_param = $method->getParameters();
			foreach($r_param as $param)
			$temp4[] = "\$".$param->getName();

			$temp4 = implode(",",$temp4);
			dump($temp4);

			$mm = new MockedMethod();
			$mm->methodName = $method->getName();
			$mm->params = $temp4;
			Mock::$mockingList[$pos]->methods[$mm->methodName] = $mm;

			runkit_method_redefine($className,$method->getName(),$temp4,$temp2);
		}

		return $clazz;
	}


	public function mockRefrenceCount($mock,$method)
	{
		dump("Called by:".$mock." Method: ".$method);

		$mm = &Mock::$mockingList[$mock]->methods[$method];
		$mm->methodName = $method;
		if(Mock::$mockingList[$mock]->replay == false)
		{
			$mm->expected++;
		} else {
			$mm->actual++;
			if($mm->multiplicity == MOCK_EQUALS && $mm->expected<$mm->actual)
			{
				throw new Exception("Unexpected call to:".Mock::$mockingList[$mock]->className."->".$method."() : Expected: ".$mm->expected." Actual: ".$mm->actual);
			}
		}

		return $mm->return;
	}

	public function mockReplay($mock)
	{
		Mock::$mockingList[$mock->mockId]->replay = true;
	}

	public function mockReturn($mock,$method,$return)
	{
		Mock::$mockingList[$mock->mockId]->methods[$method]->return = $return;
	}

	public function mockRule($mock, $method, $mode, $var)
	{
		Mock::$mockingList[$mock->mockId]->methods[$method]->multiplicity = $mode;
		Mock::$mockingList[$mock->mockId]->methods[$method]->multiplicity_var = $var;
	}

	public function mockVerify($mock)
	{
		dump("Sizeof: ".sizeof(Mock::$mockingList[$mock->mockId]->methods));
		foreach(Mock::$mockingList[$mock->mockId]->methods as $method)
		{
			dump("Method: ".$method->methodName);
			if($method->multiplicity == MOCK_ANY)
			{
				dump("MOCK_ANY");
			}
			else if($method->multiplicity == MOCK_EQUALS)
			{
				dump("MOCK_EQUALS Expected: ".$method->expected." : Actual: ".$method->actual);
					
				if($method->expected != $method->actual)
				{
					throw new Exception("Too few calls to:".Mock::$mockingList[$mock->mockId]->className."->".$method->methodName."(".$method->params.") : Expected: ".$method->expected." Actual: ".$method->actual);
				}
			} else if($method->multiplicity == MOCK_ATLEAST)
			{
				dump("MOCK_ATLEAST Times: ".$method->multiplicity_var." : Actual: ".$method->actual);
					
				if($method->multiplicity_var >= $method->actual)
				{
					throw new Exception("Too few calls to:".Mock::$mockingList[$mock->mockId]->className."->".$method->methodName."(".$method->params.") : Expected greater or equal to: ".$method->multiplicity_var." Actual: ".$method->actual);
				}
			} else if($method->multiplicity == MOCK_TIMES)
			{
				dump("MOCK_TIMES Times: ".$method->multiplicity_var." : Actual: ".$method->actual);
					
				if($method->multiplicity_var != $method->actual)
				{
					throw new Exception("Incorrect Number of calls:".Mock::$mockingList[$mock->mockId]->className."->".$method->methodName."(".$method->params.") : Expected equal to: ".$method->multiplicity_var." Actual: ".$method->actual);
				}
			}
		}
	}
}



*/
?>
